package org.raymond.iworks.study.redis.redisson;

import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RReadWriteLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author raymond
 * @version V1.0
 * @Description: TODO
 */
@Slf4j
public class ReadWriteLockTest {
    private static int count = 0;

    public static void main(String[] args) throws InterruptedException {
        test1();
    }

    public static void test1() throws InterruptedException {
        RedissonClient client = client();
        RReadWriteLock rwLock = client.getReadWriteLock("mylock");
        RLock rLock1 = rwLock.readLock();
        RLock rLock2 = rwLock.readLock();
        RLock wLock = rwLock.writeLock();
        ThreadPoolExecutor pool = new ThreadPoolExecutor(5, 5,
                0, TimeUnit.SECONDS, new LinkedBlockingQueue());
        Runnable r1 = ()->{
            log.info("rlock1...");
            rLock1.lock(2, TimeUnit.SECONDS);
            log.info("rlock1 count:{}", count);
            rLock1.unlock();
            log.info("unrlock1");
        };
        Runnable r2 = ()->{
            log.info("rlock2...");
            rLock2.lock(2, TimeUnit.SECONDS);
            log.info("rlock2 count:{}", count);
            rLock2.unlock();
            log.info("unrlock2");
        };
        Runnable r3 = ()->{
            log.info("wlock...");
            wLock.lock(2, TimeUnit.SECONDS);
            count++;
            log.info("wlock count:{}", count);
            wLock.unlock();
            log.info("unWlock");
        };
        Runnable r4 = ()->{
            log.info("no lock count:{}", count++);
        };
        log.info("pool start");
        pool.execute(r3);
        pool.execute(r4);
        pool.execute(r1);
        pool.execute(r4);
        pool.execute(r1);
        Thread.sleep(1000);
        pool.execute(r4);
        pool.execute(r1);
        pool.execute(r2);
        Thread.sleep(1000);
        pool.execute(r4);
        pool.execute(r3);

        log.info("pool shutdown but wait thread");
        Thread.sleep(3500);
        log.info("shutdown");
        pool.shutdown();
        client.shutdown();
    }

    public static RedissonClient client(){
        Config cfg = new Config();
        cfg.useSingleServer().setAddress("redis://192.168.0.125:6379");
        RedissonClient client = Redisson.create(cfg);
        return client;
    }
}
